跳到主要内容

SpringSecurity 单点登陆 SSO

参考资料 单点登录(一)

单点登录是什么?

在开始介绍之前先来看几个问题:

  1. 我们日常的办公系统是不是有多个?
  2. 每个系统之间是不是都有独立的账号密码?
  3. 密码多了,有时候半天想不起来哪个密码对应哪个系统?
  4. 每次新项目的开发,都需要重新开发和维护一套用户密码?
  5. 维护多套系统的用户是不是非常头疼?

单点登录SSO(Single Sign on):一个多系统共存的环境下,用户在一处的登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。

举个例子,京东那么复杂的系统肯定不会是单体结构,必然是微服务架构,比如订单功能是一个系统,交易是一个系统…那么我在下订单的时候登录了,付钱难道还需要再登录一次吗,如果是这样,用户体验也太差了吧。实现的流程就是我在下单的时候系统发现我没登录就让我登录,登录完了之后系统返回给我一个Token,就类似于身份证的东西;然后我想去付钱的时候就把Token再传到交易系统中,然后交易系统验证一下Token就知道是谁了,就不需要再让我登录一次。

以下两个是要点:

  • 存储信任
  • 验证信任

这个 SSO 并没有规定怎么实现,所以下面介绍几种常用的方式

最简单的单点登录实现方式,是使用cookie作为媒介,存放用户凭证。用户登录父应用后,应用返回一个加密的cookie,当用户访问子应用的时候,会携带这个cookie,授权应用解密cookie并进行验证,校验通过则登录当前用户

此方式:cookie不安全,不能跨域实现免密登录。

通过 JSONP 实现

对于跨域问题,可以采用 JSONP实现

用户在父应用登录后,跟 session匹配的 cookie会存到客户端中,当用户需要登录子应用时,授权应用访问父应用提供的 JSONP接口,并在请求中带上父应用域名下的 cookie,父应用接收到请求,验证用户的登录状态,返回加密的信息,子应用通过解析返回来的加密信息来验证用户,如果通过验证则登录用户。

通过页面重定向的方式

通过父应用和子应用来回重定向进行通信,实现信息的安全传递。

父应用提供一个 GET 方式的登录接口,用户通过子应用重定向连接的方式访问这个接口,如果用户还没有登录,则返回一个登录页面,用户输入账号密码进行登录。如果用户已经登录了,则生成加密的 Token,并且重定向到子应用提供的验证 Token 的接口,通过解密和校验之后,子应用登录当前用户。

此方法解决了安全问题和跨域问题,但是没有前面两种方便。

使用独立登录系统

一般来说,大型应用会把授权的逻辑与用户信息的相关逻辑独立成一个应用,称为用户中心。

用户中心不处理业务逻辑,只是处理用户信息的管理及授权给第三方应用,第三方应用需要登录的时候,则把用户的登录请求转发给用于中心进行处理,用户处理完毕返回凭证,第三方应用验证凭证,通过后就登录用户。

比如用 LDAP 来做这个用户中心

统一身份认证主要是改变原有的认证策略,使需要认证的软件都通过 LDAP 进行认证,在统一身份认证之后,用户的所有信息都存储在 AD Server 中。终端用户在需要使用公司内部服务的时候,都需要通过 AD服务器的认证。